﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ufida.u9.ait.openapi.utils;
using UFIDA.U9.AR.ARBill;
using UFIDA.U9.Base;
using UFIDA.U9.Base.Currency;
using UFIDA.U9.Base.Doc;
using UFIDA.U9.CBO.FI.Tax;
using UFIDA.U9.CBO.HR.Department;
using UFIDA.U9.CBO.HR.Operator;
using UFIDA.U9.CBO.SCM.AccrueBy;
using UFIDA.U9.CBO.SCM.Customer;
using UFIDA.U9.CBO.SCM.Item;
using UFIDA.U9.ISV.AR;
using UFSoft.UBF.Business;

namespace ufida.u9.ait.openapi
{
    internal class ARBillBase
    {
        public static void DeleteDoc(ARBillHead doc)
        {
            //调用产业链服务
            DeleteImportARBillSV sv = new DeleteImportARBillSV();
            sv.ImportARBillQueryConditionDTOs = new List<ImportARBillQueryConditionDTO>() { new ImportARBillQueryConditionDTO() { ID = doc.ID } };
            sv.Do();

        }

        public static void UnApproveDoc(ARBillHead doc)
        {
            //改为调用标准方法
            ARBillCancelApproveBP bp = new ARBillCancelApproveBP
            {
                ARBillHeadKey = doc.Key,
                CurrentSysVersion = doc.SysVersion,
            };
            bp.Do();
        }

        public static ARBillHead SubmitDoc(ARBillHead doc)
        {
            doc = doc.Key.GetEntity();
            //提交逻辑
            using (ISession session = Session.Open())
            {
                doc.DocStatus = UFIDA.U9.CBO.FI.Enums.BillStatusEnum.Approving;

                session.Commit();
            }
            return doc;
        }

        public static ARBillHead ApproveDoc(ARBillHead doc)
        {

            if (doc.DocStatus == UFIDA.U9.CBO.FI.Enums.BillStatusEnum.Opened)
            {
                SubmitDoc(doc);
            }


            //审核逻辑
            //启用事务后,调用BP会导致卡死,可能是因为BP也启用事务RN
            //ARBillApproveBP bp = new ARBillApproveBP
            //{
            //    ARBillHeadKey = doc.Key,
            //    CurrentSysVersion = doc.SysVersion
            //};
            //bp.Do();

            doc = doc.Key.GetEntity();
            bool actionFromUI = doc.ActionFromUI;
            using (ISession session = Session.Open())
            {
                doc.ActionFromUI = true;
                doc.DoApproving();
                session.Commit();
            }
            doc.ActionFromUI = actionFromUI;

            return doc;
        }

        public static ARBillHead CreateDoc(ARBillAITDTOData dto)
        {
            ARBillHead doc = null;
            using (ISession session = Session.Open())
            {
                doc = CreateHead(dto);
                CreateLines(doc, dto);
                session.Commit();
            }
            return doc;
        }

        private static ARBillHead CreateLines(ARBillHead doc, ARBillAITDTOData dto)
        {
            int rowno = 0;
            foreach (var linedto in dto.ARBillLines)
            {
                rowno += 10;
                ARBillLine line = ARBillLine.Create(doc);
                if (linedto.LineNum > 0)
                {
                    line.LineNum = linedto.LineNum;
                }
                else
                {
                    line.LineNum = rowno;
                }
                line.BizOrg = doc.Org;
                line.SrcOrg = doc.Org;
                line.InvoiceOrg = doc.Org;
                //料品
                if (linedto.Item != null)
                {
                    ItemMaster item = EntityUtils.GetEntityByCode<ItemMaster>(linedto.Item.ItemCode);
                    line.Item = new ItemInfo()
                    {
                        ItemID = item,
                        ItemCode = item.Code,
                        ItemName = item.Name,
                    };
                    line.TUom = item.SalesUOM;
                    line.TBUom = item.SalesUOM.BaseUOM;
                    line.PUom = line.TUom;
                    line.PBUom = line.TBUom;
                }

                //数量/价格/金额
                line.PUAmount = linedto.PUAmount;//数量
                //税组合
                if (linedto.TaxSchedule != null)
                {
                    //优先 取行传入
                    line.TaxSchedule=EntityUtils.GetEntityByCode<TaxSchedule>(linedto.TaxSchedule.Code);
                }
                else if(doc.TaxSchedule != null)
                {
                    //其次 取头传入
                    line.TaxSchedule = doc.TaxSchedule;
                }
                else if (line.Item!=null&&line.Item.ItemID!=null&&line.Item.ItemID.SaleInfo.SaleTaxSchedule != null)
                {
                    //其次 物料税组合
                    line.TaxSchedule = line.Item.ItemID.SaleInfo.SaleTaxSchedule;
                }
                if (line.TaxSchedule == null) throw new Exception("头/行/物料上的TaxSchedule为空");
                decimal taxRate = line.TaxSchedule.TaxScheduleTaxs[0].Tax.TaxRate;//税率

                line.TaxPrice = linedto.TaxPrice;//含税价
                //不含税价,传入优先,否则计算
                if (linedto.NonTaxPrice > 0)
                {
                    line.NonTaxPrice = linedto.NonTaxPrice;
                }
                else
                {
                    line.NonTaxPrice = linedto.TaxPrice / (1 + taxRate);
                    line.NonTaxPrice = U9Utils.GetRoundPrice(doc.AC, line.NonTaxPrice);
                }
                //价税合计,税额,不含税金额
                decimal total = 0;
                if (linedto.TotalMoney > 0)
                {
                    total = linedto.TotalMoney;//价税合计
                }
                else
                {
                    total = line.TaxPrice * line.PUAmount;
                }
                decimal nonTax = linedto.TotalMoney / (1 + taxRate);//不含税金额
                nonTax = U9Utils.GetRoundPrice(doc.AC, nonTax);
                decimal tax = linedto.TotalMoney - nonTax;//税额

                line.AROCMoney = new UFIDA.U9.CBO.FI.PropertyTypes.ARAPSingleCurrencyMoney()//	核币金额
                {
                    TotalMoney = total,//价税合计
                    Tax = tax,//税额
                    NonTax = nonTax,//不含税金额
                    GoodsTax = tax,//税额
                };
                line.ARFCMoney = line.AROCMoney;//本币金额

                //其它
                line.TUomToTBUom = 1;
                line.TBUomToPBUom = 1;
                line.PUomToPBUom = 1;

                line.Memo = linedto.Memo;
                line.Transactor = doc.Transactor;
                line.Dept = doc.Dept;

                line.RecTerm = doc.RecTerm;
                line.Maturity = doc.BusinessDate;
                line.IsTaxScheduleEnable = true;
                line.IsOccupyCredit = true;
                line.IsModifyAmount = true;
                line.IsCanModPrice = true;
                line.IsCanMod = true;
                line.AccrueTerm = doc.AccrueTerm;

                //扩展字段处理
                if (linedto.DescFlexField != null)
                {
                    line.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
                    DTOUtils.DTOPropCopy(linedto.DescFlexField, line.DescFlexField);
                }

                CreateTax(line, linedto);
                CreateAccrueLine(line, linedto);
            }
            return doc;
        }
        /// <summary>
        /// 创建行下的应收单合并立账来源数据
        /// </summary>
        /// <param name="line"></param>
        /// <param name="linedto"></param>
        /// <exception cref="NotImplementedException"></exception>
        private static void CreateAccrueLine(ARBillLine line, ARBillLineAITDTOData linedto)
        {
            ARBillMergeAccrueLine accline = ARBillMergeAccrueLine.Create(line);
            accline.ARBillMergeLineNum = 10;
            accline.TaxPrice = line.TaxPrice;
            accline.SrcOrg = line.SrcOrg;
            accline.PUAmount = line.PUAmount;
            accline.NonTaxPrice = line.NonTaxPrice;
            accline.AROCMoney = line.AROCMoney;
            accline.ARFCMoney = line.ARFCMoney;

            ARBillMergeAccrueTaxDetail taxline = ARBillMergeAccrueTaxDetail.Create(accline);
            taxline.LineNum = 1;
            taxline.Tax = line.TaxSchedule.TaxScheduleTaxs[0].Tax;
            taxline.TaxRate = taxline.Tax.TaxRate;
            taxline.TaxMoney = new UFIDA.U9.CBO.FI.PropertyTypes.FAMoney()
            {
                OCMoney = line.AROCMoney.Tax,
                FCMoney = line.ARFCMoney.Tax,
            };

        }
        /// <summary>
        /// 创建行下的税子行
        /// </summary>
        /// <param name="line"></param>
        /// <param name="linedto"></param>
        private static void CreateTax(ARBillLine line, ARBillLineAITDTOData linedto)
        {
            ARBillTaxDetail taxline = ARBillTaxDetail.Create(line);
            taxline.LineNum = 1;
            //税=税组合->税组合税别(行)->税别
            taxline.Tax = line.TaxSchedule.TaxScheduleTaxs[0].Tax;
            taxline.TaxRate = taxline.Tax.TaxRate;
            taxline.TaxMoney = new UFIDA.U9.CBO.FI.PropertyTypes.FAMoney()
            {
                OCMoney = line.AROCMoney.Tax,
                FCMoney = line.ARFCMoney.Tax,
            };
        }

        private static ARBillHead CreateHead(ARBillAITDTOData dto)
        {
            ARBillHead doc = ARBillHead.Create();
            doc.DocNo = dto.DocNo;
            if (String.IsNullOrEmpty(dto.BusinessDate))
            {
                throw new Exception("BusinessDate不能为空");
            }
            doc.BusinessDate = DateTime.Parse(dto.BusinessDate);
            if (dto.DocumentType == null) throw new Exception("DocumentType不能为空");
            doc.DocumentType = EntityUtils.GetEntityByCode<ARDocType>(dto.DocumentType.Code);
            doc.BusinessType = doc.DocumentType.BusinessType;
            doc.SrcBusinessType = BusinessTypeEnum.SD_StandardSale;
            //单据方向
            if(dto.DocumentType.Code== "02"|| dto.DocumentType.Code == "04")
            {
                //贷项通知单/贷项账户单
                //doc.DocDirect = UFIDA.U9.CBO.FI.Enums.BillDirectEnum.Minus;
                doc.SetValue("DocDirect", UFIDA.U9.CBO.FI.Enums.BillDirectEnum.Minus.Value);
            }
            else
            {
                doc.SetValue("DocDirect", UFIDA.U9.CBO.FI.Enums.BillDirectEnum.Plus.Value);
            }

            //组织
            doc.Org = Context.LoginOrg;
            doc.SrcOrg = doc.Org;
            doc.SettleOrg = doc.Org;
            doc.InvoiceOrg = doc.Org;
            doc.BizOrg = doc.Org;

            //doc.SOB = EntityUtils.getSetofBooks();
            //客户
            if (dto.PayCust == null) throw new Exception("PayCust不能为空");
            Customer customer = EntityUtils.GetEntityByCode<Customer>(dto.PayCust.Code);
            doc.PayCust = new CustomerMISCInfo()
            {
                Customer = customer,
                Code = customer.Code,
                Name = customer.Name,
                ShortName = customer.ShortName,
            };
            if (customer.CustomerSites == null || customer.CustomerSites.Count == 0)
                throw new Exception($"客户[{customer.Code}]位置为空");
            doc.PayCustSite = new CustomerSiteMISCInfo()
            {
                CustomerSite = customer.CustomerSites[0],
                Code = customer.CustomerSites[0].Code,
                Name = customer.CustomerSites[0].Name,
            };
            doc.CreditControlSite = customer.CustomerSites[0];
            doc.AccrueCust = doc.PayCust;
            doc.AccrueCustSite = doc.PayCustSite;

            //扩展字段处理
            if (dto.DescFlexField != null)
            {
                doc.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
                DTOUtils.DTOPropCopy(dto.DescFlexField, doc.DescFlexField);
            }

            //其它
            doc.ACToFCExRate = 1;
            doc.Transactor = EntityUtils.GetEntityByCode<Operators>(dto.Transactor);
            doc.Dept = EntityUtils.GetEntityByCode<Department>(dto.Dept);
            doc.TaxSchedule = EntityUtils.GetEntityByCode<TaxSchedule>(dto.TaxSchedule);
            
            if (customer.RecervalTerm == null) throw new Exception($"客户[{customer.Code}]收款条件为空");
            doc.RecTerm = customer.RecervalTerm;
            doc.RCR = UFIDA.U9.CBO.Enums.RevenueConfirmRuleEnum.SameToARCfm;
            doc.PriorityGrade = UFIDA.U9.CBO.FI.Enums.PriorityGradeEnum.E;
            doc.PostPeriod = EntityUtils.getPostPeriod(doc.BusinessDate);
            doc.Memo = dto.Memo;
            doc.IsTaxPrice = true;
            if (dto.AC == null)
            {
                dto.AC = new CopyOfCommonArchiveDataDTOData()
                {
                    Code = "C001"
                };
            }
            doc.AC = EntityUtils.GetEntityByCode<Currency>(dto.AC);
            
            doc.AccrueTerm = customer.ARConfirmTerm;//立账条件
            doc.AccrueDate = doc.BusinessDate;//立账日期
            doc.AccrueBy = EntityUtils.GetEntityByCode<AccrueBy>(dto.AccrueBy);//立账依据

            return doc;
        }
    }
}
